      !> @brief subrotina para a escolha automática do número de classes para a clusterização.
      !> A escolha é baseada no menor erro entre a imagem e a imagem clusterizada. 
      subroutine numclassesIm(Nclasses,X)

      use globais
      implicit none



      double precision :: X(nx0*nz0) !< vetor de incógnitas do problema inverso, relacionado à imagem
      integer :: Nclasses !< Número de classes para a clusterização


      integer :: i,j
      integer :: ierr !< Indica se houve erro na alocação de memória
      integer :: kncl !< Contador do número de classes.
      double precision :: erro !< erro entre a imagem original e a clusterizada com kncl .
      double precision :: errobest !< menor valor do erro entre a imagem original e a clusterizada com Nclasses.

!       double precision, dimension(:), allocatable :: Xaux !< variaveis de otimizacao/parametros da inversao auxiliar (imagem original).
      double precision, dimension(:,:), allocatable :: c0aux  !< modelo de velocidade referente ao Xaux (imagem original).


      double precision :: mapCemX
!       double precision :: cmin
!       double precision :: cmax


      double precision :: lamdanaux

!       write(*,*)'alocando Xaux...'
!       allocate(xaux(nx0*nz0))

      write(*,*)'alocando c0aux...'
      allocate(c0aux(nx0,nz0))

      call modelo2d(X)! aqui, X é original, crio c0
!       do i=1,nx0*nz0
! 	  Xaux(i) = X(i) ! guardo X original em Xaux
!       enddo
      do j=1,nz0
	  do i=1,nx0
	      c0aux(i,j) = c0(i,j) ! guardo c0 original em c0aux
	  enddo
      enddo
    


      do kncl = 2,int(nz0/3) !< busca o melhor numero de classes para a clusterização.
	  call modelo2d(X) ! do X original, crio a matriz c0
	  call clusteriza(c0,nx0,nz0,kncl) ! clusterizo a matriz c0

	  if(suav.eq.1)then
	      call suaviza(c0,nx0,nz0) ! suavizo a matriz c0
	  endif

	  erro = 0.0d0
	  do j=1,nz0
	      do i=1,nx0
		  erro = erro + (c0aux(i,j) - c0(i,j))**2 ! calculo o erro da clusterização com kncl classes em relação à imagem original
	      enddo
	  enddo
	  erro = sqrt(erro)*dfloat(kncl)
	  write(*,*)'kncl,erro',kncl,erro

	  if(kncl.eq.2)then
	      Nclasses = kncl
	      errobest = erro
	  elseif(erro.lt.errobest)then ! avalio o novo modelo
	      Nclasses = kncl
	      errobest = erro
	  endif
	  if(kncl.ge.(Nclasses+3))exit
      enddo

      !< retorno apenas Nclasses, c0 deve ser recalculado

      deallocate(c0aux)
!       deallocate(Xaux)


      return
      end subroutine numclassesIm 
